using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL
{
    public class DemoStateMachine : RapidHardware
    {
        public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = false;
            Settings.ForceBuildHardware = false;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 1;
            Settings.UseSDRAM = true;
            Settings.BuildRemote = true;
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            /* Up Counter */
            UpCounter oUpCounter = new UpCounter(TopLevelComponent, "counter", TopLevelComponent.MainClock, 14, true, true, 0, 20, 2);
            SystemInterface.AddSignalSource("enable", oUpCounter.EnableIn, 1);
            oUpCounter.ResetIn.Connection = TopLevelComponent.MainReset;

            TopLevelComponent.TestBusWrite.ConnectSubset(0, 0, oUpCounter.CountOut, 4, 4);
            TopLevelComponent.TestBusWrite.ConnectSubset(1, 12, Operators.CONST(TopLevelComponent, 0, 12), 0, 11);
            

            /* State machine*/
            StateMachine oStateMachine = new StateMachine(TopLevelComponent, "state_machine", TopLevelComponent.MainClock);
            oStateMachine.ResetIn.Connection = TopLevelComponent.MainReset;

            NodeVector nvGo = new NodeVector(TopLevelComponent, "GO_I", 1);
            NodeVector nvFinish = new NodeVector(TopLevelComponent, "FINISH_I", 1);

            SystemInterface.AddSignalSource("Go", nvGo, 1);
            SystemInterface.AddSignalSource("Finish", nvFinish, 0);            

            oStateMachine.AddState("state_a");
            oStateMachine.AddState("state_b");
            oStateMachine.AddState("state_c");
            oStateMachine.AddState("state_d");
            oStateMachine.AddState("state_e");

            oStateMachine.SetDefaultState("state_a");

            oStateMachine.StateTransition("state_a", nvGo, "state_b");
            oStateMachine.StateTransition("state_b", "state_c");
            oStateMachine.StateTransition("state_c", Operators.NOT(TopLevelComponent,nvFinish), "state_e");
            oStateMachine.StateTransition("state_c", nvFinish, "state_d");
            oStateMachine.StateTransition("state_d", "state_a");
            oStateMachine.StateTransition("state_e", "state_b");
            
            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            SystemInterface.AddSignalView("count", "counter.COUNT_O");
            SystemInterface.FormatSignalView("count", SignalFormat.Unsigned);
            
            SystemInterface.AddSignalView("state_machine.current_state.DATA_O");

            return true;
        }

    }
}
